<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    h3 {
      line-height: 60px;
    }

    li {
      list-style: none;
      line-height: 40px;
      border: 1px dashed #333;
    }

    .list {
      overflow: hidden;
    }
  </style>
</head>

<body>
  <div class="wrap">
    <h3 id="title">批量操作元素</h3>
    <ul class="list">
      <li>01</li>
      <li>02</li>
      <li>03</li>
      <li>04</li>
      <li>05</li>
      <li>06</li>
    </ul>
    <!-- <input type="text" class="demo"> -->
  </div>
  <div class="box">
    <button class="setHtml">
      设置html
    </button>
    <button class="getHtml">
      获取html
    </button>
    <button class="hide">隐藏</button>
    <button class="show">显示</button>
    <button class="setWidth">
      设置宽度
    </button>
    <button class="getWidth">
      获取宽度
    </button>
    <button class="attr">attr</button>
    <button class="prop">prop</button>
    <button class="css">css</button>
    <button class="addClass">addClass</button>
    <button class="removeClass">removeClass</button>
    <button class="eq">eq</button>
    <button class="siblings">siblings</button>
    <button class="chain">链式操作</button>
  </div>
</body>
<script>
  // 面向过程

  // 操作 -> 单元素 => 直接操作
  // var title = document.getElementById("title");
  // console.log(title.innerHTML);
  // title.innerHTML = "标题";

  // 操作 -> 多元素 => 遍历获取 在操作
  // var liList = document.querySelectorAll(".list li");
  // for (var i = 0; i < liList.length; i++) {
  //     var li = liList[i];
  //     li.innerHTML = "123123";
  // }

  // => 批量操作元素 => 有可能是单元素,多元素  => 方法有区别
  // 使用 document.querySelectorAll()  无论是单元素获取还是多元素 => 都会存放到集合中

  // debugger;
  // 接收一个css选择器 作为参数
  function GetEle(selector) {
    // {}
    // this -> {}

    this.eles = document.querySelectorAll(selector);
    // this.[[prototype]] = GetEle.prototype
    // return this;
  }

  // 获取和设置 集合中元素 html结构
  // html("123123")   有参数就设置
  // html()           没有参数就获取
  GetEle.prototype.html = function (con) {
    // debugger;
    // this => 指向调用此方法的实例化对象 => 它也可以使用原型对象(prototypes)上的属性和方法 
    if (arguments.length >= 1) {  // 有参数就设置
      // for (var i = 0; i < this.eles.length; i++) {
      //     var ele = this.eles[i];
      //     ele.innerHTML = con;  // arguments[0]
      // }
      this.each(function (ele) {
        ele.innerHTML = con;
      })
    } else {   //没有参数就获取
      return this.eles[0].innerHTML;
    }
  }
  // 获取和设置 集合中元素 text结构
  // text("123123")   有参数就设置
  // text()           没有参数就获取
  GetEle.prototype.text = function (con) {
    if (arguments.length >= 1) {  // 有参数就设置
      // for (var i = 0; i < this.eles.length; i++) {
      //     var ele = this.eles[i];
      //     ele.innerText = con;  // arguments[0]
      // }
      this.each(function (ele) {
        ele.innerText = con;
      })
    } else {   //没有参数就获取
      return this.eles[0].innerText;
    }
  }

  // 获取和设置 集合中表单元素 value值
  // value("123123")   有参数就设置
  // value()           没有参数就获取
  GetEle.prototype.val = function (con) {
    if (arguments.length >= 1) {  // 有参数就设置
      // for (var i = 0; i < this.eles.length; i++) {
      //     var ele = this.eles[i];
      //     ele.value = con;  // arguments[0]
      // }
      this.each(function (ele) {
        ele.value = con;
      })
    } else {   //没有参数就获取
      return this.eles[0].value;
    }
  }

  // 设置 集合中元素  隐藏
  GetEle.prototype.hide = function () {
    // for (var i = 0; i < this.eles.length; i++) {
    //     var ele = this.eles[i];
    //     ele.style.display = "none";
    // }
    this.each(function (ele) {
      ele.style.display = "none";
    })
  }
  GetEle.prototype.show = function () {
    // for (var i = 0; i < this.eles.length; i++) {
    //     var ele = this.eles[i];
    //     ele.style.display = "block";
    // }
    this.each(function (ele) {
      ele.style.display = "block";
    })
  }

  GetEle.prototype.click = function (fn) {
    this.each(function (ele) {
      ele.onclick = fn;
    })
  }

  GetEle.prototype.each = function (fn) {
    // this -> 调用此方法的实例化对象  {eles:[]}

    for (var i = 0; i < this.eles.length; i++) {
      var item = this.eles[i];
      var index = i;
      var array = this.eles;
      fn(item, index, array);

      // jquery中 它的each方法 参数顺序 fn(index, item);

    }
  }

  // width() 获取和设置元素的宽度 
  // width("100px")  有参数就设置
  // width()         没有参数就获取

  GetEle.prototype.width = function (con) {
    if (arguments.length >= 1) {
      this.each(function (ele) {

        // 是否有单位?
        //   有单位   px pt  %  em rem vw  vh   => 直接拼接
        // 没有单位   200                       => 默认"px"
        var unit = /^\d+(\.\d+)?(px|pt|%|em|rem|vw|vh)$/
        if (unit.test(con)) {
          ele.style.width = con;
        } else {
          ele.style.width = con + "px";
        }
      })
    } else {
      // return this.eles[0].style.width;  // 只能获取内联样式
      // return parseInt(getStyle(this.eles[0], "width"));
      return parseInt(this.getStyle("width"));
    }
  }

  GetEle.prototype.height = function (con) {
    if (arguments.length >= 1) {
      this.each(function (ele) {

        // 是否有单位?
        //   有单位   px pt  %  em rem vw  vh   => 直接拼接
        // 没有单位   200                       => 默认"px"
        var unit = /^\d+(\.\d+)?(px|pt|%|em|rem|vw|vh)$/
        if (unit.test(con)) {
          ele.style.height = con;
        } else {
          ele.style.height = con + "px";
        }
      })
    } else {
      // return this.eles[0].style.height;
      // return parseInt(getStyle(this.eles[0], "height"));
      return parseInt(this.getStyle("height"));
    }
  }

  GetEle.prototype.getStyle = function (attr) {
    var ele = this.eles[0]; //默认获取集合中的第一个
    if (window.getComputedStyle) {
      return window.getComputedStyle(ele)[attr];
    } else {
      return ele.currentStyle[attr];
    }
  }

  // attr()   获取和设置标签内的属性(属性节点)
  // attr(key,val) 两个参数    setAttribute()
  // attr(key)     一个参数    getAttribute()

  GetEle.prototype.attr = function (key, val) {
    if (arguments.length >= 2) {
      this.each(function (ele) {
        ele.setAttribute(key, val);
      })
    } else if (arguments.length == 1) {
      return this.eles[0].getAttribute(key);
    } else {
      var err = new SyntaxError("place entry at last one paramter!");
      throw err;
    }
  }


  // prop()   获取和设置元素节点的属性
  // prop(key,val)  两个参数    ele.className = "a"
  // prop(key)      一个参数    ele.className

  GetEle.prototype.prop = function (key, val) {
    if (arguments.length >= 2) {   // 两个参数
      this.each(function (ele) {
        ele[key] = val;
      })
    } else if (arguments.length == 1) {  //  一个参数
      return this.eles[0][key];
    } else {
      var err = new SyntaxError("pleace entry at least one paramter!");
      throw err;
    }
  }

  // css()   获取和设置元素的样式
  // css("background","red")   两个参数 设置样式
  // css("background")         一个参数 获取样式

  GetEle.prototype.css = function (key, val) {
    if (arguments.length >= 2) {   // 两个参数
      this.each(function (ele) {
        ele.style[key] = val;
      })
    } else if (arguments.length == 1) {
      //  一个参数  (a.如果参数是一个对象 遍历获取键值对 => 设置   b.是字符串 => 获取)
      if (typeof arguments[0] == "object") {
        for (var k in arguments[0]) {
          var v = arguments[0][k];
          this.css(k, v);
        }
      } else if (typeof arguments[0] == "string") {
        return this.getStyle(key);
      }
    } else {
      var err = new SyntaxError("pleace entry at least one paramter!");
      throw err;
    }
  }











  // function getStyle(ele, attr) {
  //     if (window.getComputedStyle) {
  //         return window.getComputedStyle(ele)[attr];
  //     } else {
  //         return ele.currentStyle[attr];
  //     }
  // }


  // 对 构造函数GetEle进行二次封装  可以根据传入的选择器 快速得到对应的实例化对象
  function $(selector) {
    return new GetEle(selector);  // {eles:[]}
  }


  $(".list li").click(function () {
    console.log(this);
  });

  $(".setHtml").click(function () {
    $(".list li").html("123123");
  })

  $(".getHtml").click(function () {
    alert($(".list li").html());
  })

  $(".hide").click(function () {
    $(".list li").hide();
  })
  $(".show").click(function () {
    $(".list li").show();
  })
  $(".setWidth").click(function () {
    // $(".list li").width("200px");
    $(".list li").width("200.5px");
    // $(".list li").width(200.5);
  })
  $(".getWidth").click(function () {
    alert($(".list li").width())
  })
  $(".attr").click(function () {
    $(".list li").attr("class", "newLi");
    $(".list li").attr("asd", "asd");
    console.log($(".list li").attr("class"));
  })
  $(".prop").click(function () {
    $(".list li").prop();
    $(".list li").prop("className", "newLi");
    console.log($(".list li").prop("classList"));
  })
  $(".css").click(function () {
    // $(".list li").css("background", "red");
    // $(".list li").css("width", "100px");
    // $(".list li").css("height", "100px");
    // $(".list li").css("float", "left");
    // $(".list li").css("text-align", "center");
    // $(".list li").css("line-height", "100px");

    console.log($(".list li").css("width"));

    $(".list li").css({
      background: "red",
      width: "100px",
      height: "100px",
      float: "left",
      textAlign: "center",
      lineHeight: "100px",
    })
  })













</script>

</html>